package com.firewolf.dto;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.hibernate.annotations.QueryHints;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

@SuppressWarnings("unchecked")
public class MainDriver {

	private EntityManagerFactory factory = null;
	private EntityManager manager = null;
	private EntityTransaction tx = null;

	@Before
	public void init() {
		factory = Persistence.createEntityManagerFactory("jpa");
		manager = factory.createEntityManager();
		tx = manager.getTransaction();
		tx.begin();
	}

	@After
	public void destory() {
		tx.commit();
		manager.close();
		factory.close();
	}

	@Test
	public void generateTable() {
	}

	/**
	 * 查询列表：getResultList
	 */
	@Test
	public void list() {
		Query query = manager.createQuery("FROM News");
		List<News> list = query.getResultList();
		System.out.println(list);
	}
	
	/**
	 * 查询单个：getSingleResult
	 * 		传递参数：
	 * 			1.拼接参数（不采纳）
	 * 			2.?传递参数，设置参数的时候下标从1开始
	 * 			3.命名参数。
	 */
	@Test
	public void singleResult(){
		//使用？占位传递参数
		Query query = manager.createQuery("FROM News where id=?");
		query.setParameter(1, 1);
		News news = (News) query.getSingleResult();
		System.out.println(news);
		
		Query query2 = manager.createQuery("FROM News where id=:id");
		query2.setParameter("id", 2);
		News n2 = (News) query2.getSingleResult();
		System.out.println(n2);
	}

	
	/**
	 * 查询部分属性：
	 * 	默认情况下查询出来的是Object的数组
	 *  可以通过调用构造器来封装成对象查出来。但是必须提供对应的构造器，如：new News(id,title)
	 */
	@Test
	public void partProperty(){
		Query query = manager.createQuery("SELECT id,title FROM News where id=?");
		query.setParameter(1, 1);
		Object[] news = (Object[]) query.getSingleResult();
		System.out.println(news);
		
		Query query2 = manager.createQuery("SELECT new News(id,title) FROM News where id=?");
		query2.setParameter(1, 1);
		News n2 = (News) query2.getSingleResult();
		System.out.println(n2);
	}
	
	/**
	 * 命名查询,需要在类上面使用下面方式创建命名SQL
	   @NamedQueries(value={
			@NamedQuery(name="findById",query="FROM News where id=?")
	   })
	 */
	@Test
	public void namedQuery(){
		Query query = manager.createNamedQuery("findById");
		query.setParameter(1, 1);
		News n2 = (News) query.getSingleResult();
		System.out.println(n2);
	}
	
	/**
	 * 使用本地SQL
	 */
	@Test
	public void nativeSQL(){
		Query query = manager.createNativeQuery("select * from t_news where id=?", News.class);
		query.setParameter(1, 1);
		News n = (News) query.getSingleResult();
		System.out.println(n);
	}
	
	/**
	 * 分页
	 */
	@Test
	public void fenye(){
		Query query = manager.createQuery("FROM News");
		query.setFirstResult(0);
		query.setMaxResults(2);
	}
	
	/**
	 * 缓存查询
	 * 默认情况下，每次查出都会重新查询，如果想缓存查询，可以使用下面方式：
	 * query.setHint(QueryHints.CACHEABLE, true);
	 * 之后就不会查询了
	 */
	@Test
	public void cacheQuery(){
		Query query = manager.createQuery("FROM News");
		query.setHint(QueryHints.CACHEABLE, true);
		List<News> list = query.getResultList();
		System.out.println(list);
		
		Query query3 = manager.createQuery("FROM News");
		query3.setHint(QueryHints.CACHEABLE, true);
		List<News> list3 = query3.getResultList();
		System.out.println(list3);
	}
	
	/**
	Group By ,Order By ，聚合函数等正常使用，update，delete语句正常写
	一些函数:
		字符串处理函数主要有：
			concat(String s1, String s2)：字符串合并/连接函数。
			substring(String s, int start, int length)：取字串函数。
			trim([leading|trailing|both,] [char c,] String s)：从字符串中去掉首/尾指定的字符或空格。
			lower(String s)：将字符串转换成小写形式。
			upper(String s)：将字符串转换成大写形式。
			length(String s)：求字符串的长度。
			locate(String s1, String s2[, int start])：从第一个字符串中查找第二个字符串(子串)出现的位置。若未找到则返回0。
		算术函数主要有 abs、mod、sqrt、size 等。Size 用于求集合的元素个数。
		日期函数主要为三个，即 current_date、current_time、current_timestamp，它们不需要参数，返回服务器上的当前日期、时间和时戳。
	 */
	@Test
	public void other(){
	}
}

